package com.onesports.intelligent.k12.polarlight.service.coach;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.onesports.framework.kit.common.util.ParamUtils;
import com.onesports.intelligent.k12.polarlight.common.domain.entity.BaseEntity;
import com.onesports.intelligent.k12.polarlight.common.errors.exceptions.BusinessException;
import com.onesports.intelligent.k12.polarlight.constant.CacheConstants;
import com.onesports.intelligent.k12.polarlight.domain.dto.common.UpdateStatesDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.operation.OperationCoachCourseDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.operation.PageOperationCoachDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.organization.*;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.*;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.*;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.AccountRole;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.BizAttachmentFile;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.WxUser;
import com.onesports.intelligent.k12.polarlight.domain.vo.common.CanChoiceDataVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.common.FileVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.course.CourseScheduleDetailVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.operation.PageOperationCoachVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.organization.*;
import com.onesports.intelligent.k12.polarlight.enums.ClassInfoStatusEnum;
import com.onesports.intelligent.k12.polarlight.enums.OrganizationStaffTypeEnum;
import com.onesports.intelligent.k12.polarlight.mapper.course.*;
import com.onesports.intelligent.k12.polarlight.mapper.organization.*;
import com.onesports.intelligent.k12.polarlight.mapper.sys.AccountRoleMapper;
import com.onesports.intelligent.k12.polarlight.mapper.sys.BizAttachmentFileMapper;
import com.onesports.intelligent.k12.polarlight.security.OrganizationNotActivatedException;
import com.onesports.intelligent.k12.polarlight.service.campus.OrganizationCampusService;
import com.onesports.intelligent.k12.polarlight.service.course.CourseScheduleService;
import com.onesports.intelligent.k12.polarlight.service.organization.OrganizationStaffService;
import com.onesports.intelligent.k12.polarlight.service.student.WxUserService;
import com.onesports.intelligent.k12.polarlight.service.sys.BizAttachmentFileService;
import com.onesports.intelligent.k12.polarlight.util.BeanCopyUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Wsy
 **/
@Service
@RequiredArgsConstructor
public class CoachService extends ServiceImpl<CoachMapper, Coach> {

    private final CoachCampusRelService coachCampusRelService;

    private final CoachCampusRelMapper coachCampusRelMapper;

    private final OrganizationStaffService organizationStaffService;

    private final WxUserService wxUserService;

    private final CoachMapper coachMapper;

    private final CoachCourseRelMapper coachCourseRelMapper;

    private final CoachScheduleTemplateRelMapper coachScheduleTemplateRelMapper;

    private final CoachMapper mapper;

    private final ClassInfoMapper classInfoMapper;

    private final CourseScheduleService courseScheduleService;

    private final BizAttachmentFileMapper bizAttachmentFileMapper;

    private final OrganizationStaffMapper organizationStaffMapper;

    private final AccountRoleMapper accountRoleMapper;

    private final CourseSubLevelMapper courseSubLevelMapper;

    private final BizAttachmentFileService bizAttachmentFileService;

    private final CourseScheduleMapper courseScheduleMapper;

    private final CourseScheduleDetailMapper courseScheduleDetailMapper;

    private final CourseScheduleTemplateMapper courseScheduleTemplateMapper;

    private final CourseScheduleDetailCoachRelMapper courseScheduleDetailCoachRelMapper;

    private final OrganizationCampusMapper organizationCampusMapper;

    private final OrganizationCampusService organizationCampusService;
    private final String COACH = "coach";


    /**
     * 教练下拉
     *
     * @param coachName      教练名称
     * @param isContainUnUse 是否只查可用教练
     * @return List<CanChoiceDataVO>
     */
    public List<CanChoiceDataVO> dropDown(String coachName, Boolean isContainUnUse) {
        List<CoachCampusRel> coachCampusRelList = this.coachCampusRelMapper.selectAuthCoachCampusRel();

        List<String> coachIds = null;
        if (ParamUtils.isNotEmpty(coachCampusRelList)) {
            coachIds = coachCampusRelList.stream().map(CoachCampusRel::getCoachId).collect(Collectors.toList());
        }

        List<Coach> list = this.list(new LambdaQueryWrapper<Coach>()
                .in(ParamUtils.isNotEmpty(coachIds), BaseEntity::getId, coachIds)
                .eq(ParamUtils.isNotEmpty(isContainUnUse) && isContainUnUse.equals(Boolean.TRUE), Coach::getStatus, isContainUnUse));


        if (ParamUtils.isEmpty(list)) {
            return new ArrayList<>();
        }

        List<String> staffIds = list.stream().map(Coach::getOrganizationStaffId).collect(Collectors.toList());

        List<OrganizationStaff> organizationStaffs = this.organizationStaffService.list(new LambdaQueryWrapper<OrganizationStaff>()
                .like(ParamUtils.isNotEmpty(coachName), OrganizationStaff::getStaffName, coachName)
                .in(BaseEntity::getId, staffIds));

        if (ParamUtils.isEmpty(organizationStaffs)) {
            return new ArrayList<>();
        }

        Map<String, String> staffMap = organizationStaffs.stream().collect(Collectors.toMap(BaseEntity::getId, OrganizationStaff::getStaffName));
        return BeanCopyUtil.copyListProperties(list, CanChoiceDataVO::new, (o, n) -> n.setName(staffMap.get(o.getOrganizationStaffId())));
    }

    /**
     * 新增教练
     *
     * @param dto 入参
     */
    @Transactional(rollbackFor = Exception.class)
    public void add(InsertCoachDTO dto) {
        // 添加教练到职工表
        OrganizationStaffDTO dtoStaff = new OrganizationStaffDTO();
        BeanCopyUtil.copyProperties(dto, dtoStaff);
        dtoStaff.setStaffName(dto.getName());
        if (!CollectionUtils.isEmpty(dto.getCoachCampusRel())) {
            dtoStaff.setCampusIds(dto.getCoachCampusRel().stream().map(CoachCampusRelDTO::getCampusId).collect(Collectors.toList()));
        }
        OrganizationStaff staff = organizationStaffService.add(dtoStaff, OrganizationStaffTypeEnum.COACH);
        String staffId = staff.getId();
        // 根据教练获取wx User
        WxUser wxUser = wxUserService.getWxUserByCoach(dto);
        // 添加教练
        Coach entity = new Coach();
        BeanCopyUtil.copyProperties(dto, entity);
        entity.setOrganizationStaffId(staffId);
        entity.setWxUserId(wxUser.getId());
        this.mapper.insert(entity);
        dto.setId(entity.getId());

        // 教练校区关联排序号处理
        coachCampusRelService.addQueueNumber(dto.getCoachCampusRel());

        // 插入教练的3个关联关系：校区、课程、排课表
        this.saveCoachRel(dto, entity.getId());

        // 判断分账比例是否大于100
        List<String> campusIds = dto.getCoachCampusRel().stream().map(CoachCampusRelDTO::getCampusId)
                .collect(Collectors.toList());
        organizationCampusService.whetherExceedSubRatio(entity.getId(),campusIds);

        // 附件表处理
        if (ParamUtils.isNotEmpty(dto.getFiles())) {
            this.saveFiles(dto.getFiles(), entity.getId());
        }

        // 插入课表详情关联教练
        this.saveCoachSchedule(dto);

    }

    /**
     * function: 保存教练可用时段和课程到课表教练关联
     *
     * @param dto 教练插入DTO
     * @author WangCX
     * @since 2022/8/7 14:56
     */
    public void saveCoachSchedule(InsertCoachDTO dto) {
        // 教练关联的课程id集合
        List<String> courseIds = dto.getCoachCourseRel().stream().map(CoachCourseRelDTO::getCourseId)
                .collect(Collectors.toList());
        // 校区id集合
        List<String> campusIds = dto.getCoachCampusRel().stream().map(CoachCampusRelDTO::getCampusId)
                .collect(Collectors.toList());
        List<CourseSchedule> courseSchedules = courseScheduleMapper.selectList(new LambdaQueryWrapper<CourseSchedule>()
                .in(CourseSchedule::getCourseId, courseIds).in(CourseSchedule::getCampusId, campusIds));
        // 课表id
        List<String> courseScheduleIds = new ArrayList<>();
        if (ParamUtils.isNotEmpty(courseSchedules)) {
            courseScheduleIds = courseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
            // 获取课程时段section_code
            List<String> templateIds = coachScheduleTemplateRelMapper
                    .selectList(new LambdaQueryWrapper<CoachScheduleTemplateRel>()
                            .in(CoachScheduleTemplateRel::getCoachId, dto.getId()))
                    .stream().map(CoachScheduleTemplateRel::getScheduleTemplateId).collect(Collectors.toList());
            List<String> sectionCodes = courseScheduleTemplateMapper.selectList(
                            new LambdaQueryWrapper<CourseScheduleTemplate>().in(CourseScheduleTemplate::getId, templateIds))
                    .stream().map(CourseScheduleTemplate::getSectionCode).collect(Collectors.toList());
            // 根据课表id集合和排课时段取得课表详情id
            List<CourseScheduleDetail> courseScheduleDetails = courseScheduleDetailMapper.selectList(
                    new LambdaQueryWrapper<CourseScheduleDetail>()
                            .in(CourseScheduleDetail::getScheduleId, courseScheduleIds)
                            .in(CourseScheduleDetail::getSectionCode, sectionCodes));
            List<String> scheduleDetailIds = new ArrayList<>();
            if (ParamUtils.isNotEmpty(courseScheduleDetails)) {
                scheduleDetailIds = courseScheduleDetails.stream().map(CourseScheduleDetail::getId)
                        .collect(Collectors.toList());
                scheduleDetailIds.forEach(f -> {
                    CourseScheduleDetailCoachRel entity = new CourseScheduleDetailCoachRel();
                    entity.setCoachId(dto.getId());
                    entity.setScheduleDetailId(f);
                    this.courseScheduleDetailCoachRelMapper.insert(entity);
                });
            }
        }

    }


    /**
     * function: 根据文件名获取文件插入数据表
     *
     * @param files 文件集合
     * @param id    业务id
     * @author WangCX
     * @since 2022/8/2 14:56
     */
    public void saveFiles(List<String> files, String id) {
        List<BizAttachmentFile> bizAttachmentFiles = new ArrayList<>();
        for (String file : files) {
            BizAttachmentFile bizAttachmentFile = new BizAttachmentFile();
            bizAttachmentFile = bizAttachmentFileService.getForCache(file);
            bizAttachmentFile.setBizId(id);
            bizAttachmentFile.setBizType(COACH);
            bizAttachmentFiles.add(bizAttachmentFile);
        }
        this.bizAttachmentFileService.saveBatch(bizAttachmentFiles);
    }

    /**
     * 修改教练信息
     *
     * @param dto 入参
     */
    @Transactional(rollbackFor = Exception.class)
    public void upd(UpdateCoachDTO dto) {
        // 添加到职工表
        Coach coach = this.getById(dto.getId());
        OrganizationStaff organizationStaff = this.organizationStaffService.getById(coach.getOrganizationStaffId());
        dto.setWxUserId(coach.getWxUserId());
        OrganizationStaffDTO staffDTO = new OrganizationStaffDTO();
        BeanCopyUtil.copyProperties(dto, staffDTO);
        staffDTO.setStaffName(dto.getName());
        staffDTO.setAccountId(organizationStaff.getAccountId());
        staffDTO.setId(coach.getOrganizationStaffId());
        if (!CollectionUtils.isEmpty(dto.getCoachCampusRel())) {
            staffDTO.setCampusIds(dto.getCoachCampusRel().stream().map(CoachCampusRelDTO::getCampusId).collect(Collectors.toList()));
        }
        organizationStaffService.edit(staffDTO, false);
        // 修改到wx User
        WxUser wxUser = wxUserService.getWxUserByCoach(dto);
        dto.setWxUserId(wxUser.getId());
        // 修改教练信息
        Coach entity = new Coach();
        BeanCopyUtil.copyProperties(dto, entity);
        this.mapper.updateById(entity);

        // 删除原来的教练校区关联关系
        LambdaQueryWrapper<CoachCampusRel> coachCampusRelLam = new LambdaQueryWrapper<>();
        coachCampusRelLam.eq(CoachCampusRel::getCoachId, dto.getId());
        coachCampusRelService.remove(coachCampusRelLam);
        // 删除原来的教练课程关联关系
        LambdaQueryWrapper<CoachCourseRel> coachCourseRelLam = new LambdaQueryWrapper<>();
        coachCourseRelLam.eq(CoachCourseRel::getCoachId, dto.getId());
        this.coachCourseRelMapper.delete(coachCourseRelLam);
        // 删除原来的教练排课模板表关联关系
        LambdaQueryWrapper<CoachScheduleTemplateRel> coachScheduleTemplateRelLam = new LambdaQueryWrapper<>();
        coachScheduleTemplateRelLam.eq(CoachScheduleTemplateRel::getCoachId, dto.getId());
        this.coachScheduleTemplateRelMapper.delete(coachScheduleTemplateRelLam);
        // 教练校区关联排序号处理
        for (CoachCampusRelDTO coachCampusRelDTO : dto.getCoachCampusRel()) {
            coachCampusRelDTO.setCoachId(dto.getId());
        }
        coachCampusRelService.addQueueNumber(dto.getCoachCampusRel());

        // 插入教练的3个关联关系：校区、课程、排课表
        this.saveCoachRel(dto, dto.getId());

        // 判断分账比例是否大于100
        List<String> campusIds = dto.getCoachCampusRel().stream().map(CoachCampusRelDTO::getCampusId).collect(Collectors.toList());
        organizationCampusService.whetherExceedSubRatio(dto.getId(),campusIds);

        // 删除课表时段详情关联教练表
        LambdaQueryWrapper<CourseScheduleDetailCoachRel> courseScheduleDetailCoachRelLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseScheduleDetailCoachRelLambdaQueryWrapper.eq(CourseScheduleDetailCoachRel::getCoachId, dto.getId());
        courseScheduleDetailCoachRelLambdaQueryWrapper.eq(CourseScheduleDetailCoachRel::getStatus, Boolean.TRUE);
        courseScheduleDetailCoachRelMapper.delete(courseScheduleDetailCoachRelLambdaQueryWrapper);
        // 插入课表详情关联教练
        this.saveCoachSchedule(dto);

        // 附件处理
        if (ParamUtils.isNotEmpty(dto.getFiles())) {
            List<BizAttachmentFile> bizAttachmentFiles = this.bizAttachmentFileMapper.selectList(new LambdaQueryWrapper<BizAttachmentFile>()
                    .eq(BizAttachmentFile::getBizId, dto.getId()).eq(BizAttachmentFile::getBizType, COACH));
            if (ParamUtils.isNotEmpty(bizAttachmentFiles)) {
                List<String> newFiles = dto.getFiles();
                List<String> files = bizAttachmentFiles.stream().map(BizAttachmentFile::getFileName).collect(Collectors.toList());
                Collections.sort(files);
                Collections.sort(newFiles);
                if (!newFiles.equals(files)) {
                    List<String> fileNames = new ArrayList<>();
                    for (String file : files) {
                        if (!newFiles.contains(file)) {
                            fileNames.add(file);
                        }
                    }
                    if (ParamUtils.isNotEmpty(fileNames)) {
                        LambdaQueryWrapper<BizAttachmentFile> lam = new LambdaQueryWrapper<>();
                        lam.in(BizAttachmentFile::getFileName, fileNames);
                        this.bizAttachmentFileMapper.delete(lam);
                    }
                    fileNames = new ArrayList<>();
                    for (String newFile : newFiles) {
                        if (!files.contains(newFile)) {
                            fileNames.add(newFile);
                        }
                    }
                    if (ParamUtils.isNotEmpty(fileNames)) {
                        this.saveFiles(fileNames, dto.getId());
                    }
                }
            } else {
                this.saveFiles(dto.getFiles(), dto.getId());
            }
        }


    }


    /**
     * function：插入教练的3个关联关系：校区、课程、排课表
     *
     * @param dto     教练插入或修改DTO
     * @param coachId 教练id
     * @author wangcx
     * @since 2022/7/28 17:06
     */
    private void saveCoachRel(InsertCoachDTO dto, String coachId) {
        // 判断是否重复校区
        List<String> campusIds = new ArrayList<>();
        // 添加到校区关联教练
        for (CoachCampusRelDTO coachCampusRel : dto.getCoachCampusRel()) {
            if (campusIds.contains(coachCampusRel.getCampusId())) {
                throw new BusinessException("重复的校区关联！");
            }
            campusIds.add(coachCampusRel.getCampusId());
            CoachCampusRel campusRel = new CoachCampusRel();
            BeanCopyUtil.copyProperties(coachCampusRel, campusRel);
            campusRel.setCoachId(coachId);
            campusRel.setOrganizationId(dto.getOrganizationId());
            coachCampusRelService.save(campusRel);
        }
        // 添加到课程关联教练
        for (CoachCourseRelDTO coachCourseRel : dto.getCoachCourseRel()) {
            CoachCourseRel courseRel = new CoachCourseRel();
            BeanCopyUtil.copyProperties(coachCourseRel, courseRel);
            courseRel.setCoachId(coachId);
            coachCourseRelMapper.insert(courseRel);
        }
        // 添加到排课时间关联教练
        for (CoachScheduleTemplateRelDTO coachScheduleTemplateRel : dto.getCoachScheduleTemplateRel()) {
            CoachScheduleTemplateRel scheduleTemplateRel = new CoachScheduleTemplateRel();
            BeanCopyUtil.copyProperties(coachScheduleTemplateRel, scheduleTemplateRel);
            scheduleTemplateRel.setCoachId(coachId);
            coachScheduleTemplateRelMapper.insert(scheduleTemplateRel);
        }

    }

    /**
     * 修改教练状态
     *
     * @param dto 入参
     */
    @CacheEvict(cacheNames = CacheConstants.TOKEN, key = "#dto.id",
            cacheResolver = "tokenEvictCacheResolver",
            condition = "#dto.status == false")
    public void updStatus(UpdateStatesDTO dto) {
        if (!dto.getStatus()) {
            List<CoachCourseRel> coachCourseRelList = coachCourseRelMapper.selectList(new LambdaQueryWrapper<CoachCourseRel>()
                    .eq(CoachCourseRel::getCoachId, dto.getId())
                    .eq(CoachCourseRel::getDeleted, false));
                LambdaQueryWrapper<ClassInfo> lam = new LambdaQueryWrapper<>();
                lam.eq(ClassInfo::getCoachId, dto.getId())
                        .in(ClassInfo::getClassStatus, Arrays.asList(
                                ClassInfoStatusEnum.FINISH_CLASS.getValue(),
                                ClassInfoStatusEnum.OPEN_CLASS.getValue(),
                                ClassInfoStatusEnum.IN_CLASS.getValue()));
                Long account = classInfoMapper.selectCount(lam);
                if (account > 0) {
                    throw new BusinessException("当前教练所在班级有正在上课班级，无法禁用！");
                }
            }
        Coach entity = new Coach();
        BeanCopyUtil.copyProperties(dto, entity);
        this.mapper.updateById(entity);
    }

    /**
     * 分页查询机构端教练信息
     *
     * @param page 分页参数
     * @param dto  入参
     * @return PageOrganizationCoachVO
     */
    public IPage<PageOrganizationCoachVO> organizationPage(Page<PageOrganizationCoachVO> page,
                                                           PageOrganizationCoachDTO dto) {
        IPage<PageOrganizationCoachVO> result = this.mapper.organizationPage(page, dto);
        if (ParamUtils.isNotEmpty(result.getRecords())) {
            // 校区筛选
            if (ParamUtils.isNotEmpty(dto.getCampusId())) {
                List<String> coachIds = coachCampusRelService.list(new LambdaQueryWrapper<CoachCampusRel>()
                                .eq(CoachCampusRel::getDeleted, false)
                                .eq(CoachCampusRel::getCampusId, dto.getCampusId())).stream()
                        .map(CoachCampusRel::getCoachId).collect(Collectors.toList());
                List<PageOrganizationCoachVO> collect = result.getRecords().stream().filter(p ->
                        coachIds.contains(p.getId())).collect(Collectors.toList());
                result.setRecords(collect);
            }
            for (PageOrganizationCoachVO record : result.getRecords()) {
                // 附件信息获取
                List<BizAttachmentFile> bizAttachmentFiles = this.bizAttachmentFileMapper
                        .selectList(new LambdaQueryWrapper<BizAttachmentFile>()
                                .eq(BizAttachmentFile::getDeleted, false).eq(BizAttachmentFile::getBizId, record.getId()));
                if (ParamUtils.isNotEmpty(bizAttachmentFiles)) {
                    List<FileVO> files = BeanCopyUtil.copyListProperties(bizAttachmentFiles, FileVO::new);
                    record.setFiles(files);
                }
                // 角色获取
                Coach coach = this.getById(record.getId());
                OrganizationStaff organizationStaff = this.organizationStaffService.getById(coach.getOrganizationStaffId());
                List<String> accountRoles = this.accountRoleMapper.selectList(new LambdaQueryWrapper<AccountRole>()
                                .eq(AccountRole::getAccountId, organizationStaff.getAccountId())
                                .exists("select 1 from sys_role where sys_role.is_super = false and sys_account_role.role_id = sys_role.id"))
                        .stream().map(AccountRole::getRoleId).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(accountRoles)) {
                    record.setRoleIds(accountRoles);
                }
                // 判断校区、时段、课程可不可以删除
                for (CoachCampusRelVO campusRelVO : record.getCoachCampusRelList()) {
                    Long count = this.classInfoMapper.selectCount(new LambdaQueryWrapper<ClassInfo>()
                            .eq(ClassInfo::getCampusId, campusRelVO.getCampusId())
                            .eq(ClassInfo::getCoachId, record.getId())
                            .in(ClassInfo::getClassStatus, ClassInfoStatusEnum.IN_CLASS.getValue(),
                                    ClassInfoStatusEnum.FINISH_CLASS.getValue(),
                                    ClassInfoStatusEnum.OPEN_CLASS.getValue()));
                    campusRelVO.setIsLink(count > 0);
                }
                for (CoachCourseRelVO courseRelVO : record.getCoachCourseRel()) {
                    Long count = this.classInfoMapper.selectCount(new LambdaQueryWrapper<ClassInfo>()
                            .eq(ClassInfo::getCourseId, courseRelVO.getCourseId())
                            .eq(ClassInfo::getCoachId, record.getId())
                            .in(ClassInfo::getClassStatus, ClassInfoStatusEnum.IN_CLASS.getValue(),
                                    ClassInfoStatusEnum.FINISH_CLASS.getValue(),
                                    ClassInfoStatusEnum.OPEN_CLASS.getValue()));
                    courseRelVO.setIsLink(count > 0);
                }
                for (CoachScheduleTemplateRelVO template : record.getCoachScheduleTemplateRel()) {
                    List<String> classStatus = new ArrayList<>();
                    classStatus.add(ClassInfoStatusEnum.IN_CLASS.getValue());
                    classStatus.add(ClassInfoStatusEnum.FINISH_CLASS.getValue());
                    classStatus.add(ClassInfoStatusEnum.OPEN_CLASS.getValue());
                    Long count = this.courseScheduleDetailMapper.countCoachLink(template.getCode(), record.getId(),classStatus);
                    template.setIsLink(count > 0);
                }
            }


        }

        return result;
    }

    /**
     * 获取教练服务信息
     *
     * @param courseId            课程id
     * @param campusId            校区id
     * @param scheduleTemplateIds 排班表id
     * @return List<CoachServeVO>
     */
    public List<CoachServeVO> serveInfo(String courseId, String campusId, List<String> scheduleTemplateIds, List<String> statusList) {
        return this.coachMapper.serveInfo(courseId, campusId, scheduleTemplateIds, statusList);
    }

    /**
     * 分页查询运营端教练信息
     *
     * @param page 分页参数
     * @param dto  入参
     * @return PageOperationCoachVO
     */
    public IPage<PageOperationCoachVO> operationPage(Page<PageOperationCoachVO> page, PageOperationCoachDTO dto) {
        IPage<PageOperationCoachVO> result = this.mapper.operationPage(page, dto);
        // 校区名称检索教练
        if (ParamUtils.isNotEmpty(dto.getCampusName()) && ParamUtils.isNotEmpty(result.getRecords())) {
            List<String> campusIds = this.organizationCampusMapper.selectList(
                            new LambdaQueryWrapper<OrganizationCampus>()
                                    .eq(OrganizationCampus::getDeleted, false)
                                    .like(OrganizationCampus::getCampusName, dto.getCampusName())).stream()
                    .map(OrganizationCampus::getId).collect(Collectors.toList());
            if (ParamUtils.isNotEmpty(campusIds)) {
                List<String> coachIds = coachCampusRelService.list(new LambdaQueryWrapper<CoachCampusRel>()
                                .eq(CoachCampusRel::getDeleted, false)
                                .in(CoachCampusRel::getCampusId, campusIds)).stream().map(CoachCampusRel::getCoachId)
                        .collect(Collectors.toList());

                result.setRecords(result.getRecords().stream().filter(v -> coachIds.contains(v.getId()))
                        .collect(Collectors.toList()));
                long count = result.getRecords().size();
                result.setTotal(count);
            } else {
                result.setRecords(null);
                result.setTotal(0);
            }

        }
        // 课程分阶id检索教练
        if (ParamUtils.isNotEmpty(dto.getSubId()) && ParamUtils.isNotEmpty(result.getRecords())) {
            CourseSubLevel courseSubLevel = this.courseSubLevelMapper.selectById(dto.getSubId());
            if (ParamUtils.isNotEmpty(courseSubLevel)) {
                String subLevelName = courseSubLevel.getSubLevelName();
                result.setRecords(result.getRecords().stream()
                        .filter(p -> p.getSubNames().contains(subLevelName)).collect(Collectors.toList()));
                long count = result.getRecords().size();
                result.setTotal(count);
            } else {
                result.setRecords(null);
                result.setTotal(0);
            }
        }
        return result;
    }


    /**
     * 运营端教练查看排课表
     *
     * @param dto 入参
     * @return CourseScheduleDetailVO
     */
    public List<CourseScheduleDetailVO> getCourse(OperationCoachCourseDTO dto) {
        return courseScheduleService.schedulePreview(dto.getScheduleId(), dto.getCampusIds(),
                dto.getCourseId(), dto.getStartTime(), dto.getEndTime(), dto.getCoachId());
    }

    /**
     * 根据微信用户查询
     *
     * @param wxUserId 微信UserId
     * @return Coach 实体类
     */
    public Coach getByWxUserId(String wxUserId) {
        return getOne(new LambdaQueryWrapper<Coach>()
                .eq(Coach::getWxUserId, wxUserId));
    }

    /**
     * function:机构端查看当前教练校区关联排序是否已存在
     *
     * @param dto 教练关联校区
     * @return 是否已存在排序
     * @author WangCX
     * @since 2022/8/3 14:13
     */
    public List<String> getSort(GetSortCoachDTO dto) {
        List<String> campusIds = new ArrayList<>();
        for (CoachCampusRelDTO relDTO : dto.getCoachCampusRel()) {
            Long aLong = coachCampusRelService.countCampusRel(relDTO);
            if (aLong > 0) {
                campusIds.add(relDTO.getCampusId());
            }
        }
        return campusIds;
    }

    public void verifyCoach(String wxUserId) {
        List<Coach> coaches = baseMapper.selectList(new LambdaQueryWrapper<Coach>().eq(Coach::getWxUserId, wxUserId).eq(Coach::getDeleted, false));
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(coaches)) {
            Coach account = coaches.get(0);
            if (!account.getStatus()) {
                throw new OrganizationNotActivatedException("当前教练已经被停用!");
            }
        } else {
            throw new OrganizationNotActivatedException("未查找到教练");
        }
    }
}
